
using System;
using System.Reflection;
using System.Collections.Generic;

namespace MvvmFx.Common.Helpers
{
    /// <summary>
    /// Common utility functions for using reflection
    /// </summary>
    public static class ReflectionHelper
    {
        /// <summary>
        /// Get a list of attribute names applied to a <see cref="System.Type"/>.
        /// </summary>
        /// <param name="type">The <see cref="System.Type"/> in question.</param>
        /// <param name="inherit">Indicated whether attributes in the type's ancestory should be considered.</param>
        /// <returns>A <see cref="System.Collections.Generic.List"/> of <see cref="System.String"/> 
        /// objects, detailing the names of any attributes found on the type.</returns>
        public static List<string> GetAttributes(Type type, bool inherit)
        {
            object[] attributes = type.GetCustomAttributes(inherit);

            List<string> result = new List<string>(attributes.Length);

            foreach (Attribute attribute in attributes)
            {
                result.Add(attribute.GetType().Name);
            }

            return result;
        }

        /// <summary>
        /// Get a list of attribute names applied to a method, defined by the supplied <see cref="System.Reflection.MethodInfo"/>.
        /// </summary>
        /// <param name="method">The <see cref="System.Relfection.MethodInfo"/> in question.</param>
        /// <param name="inherit">Indicated whether attributes in the method's ancestory should be considered.</param>
        /// <returns>A <see cref="System.Collections.Generic.List"/> of <see cref="System.String"/> 
        /// objects, detailing the names of any attributes found on the method.</returns>
        public static List<string> GetAttributes(MethodInfo method, bool inherit)
        {
            object[] attributes = method.GetCustomAttributes(inherit);

            List<string> result = new List<string>(attributes.Length);

            foreach (Attribute attribute in attributes)
            {
                result.Add(attribute.GetType().Name);
            }

            return result;
        }

        public static bool HasAttribute<T>(Type type, bool inherit) where T : Attribute
        {
            bool hasAttribute = (type.GetCustomAttributes(typeof(T), inherit).Length > 0);

            return hasAttribute;
        }

        public static bool HasAttribute<T>(MemberInfo type, bool inherit) where T : Attribute
        {
            bool hasAttribute = (type.GetCustomAttributes(typeof(T), inherit).Length > 0);

            return hasAttribute;
        }

        public static bool HasAttribute<T>(object obj, bool inherit) where T : Attribute
        {
            return HasAttribute<T>(obj.GetType(),inherit);
        }
    }
}